package com.xbongbong.paas.service.dynamic.crm.strategy.impl;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasStageEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.enums.StageTypeEnum;
import com.xbongbong.paas.log.constant.CrmLogMemoConstant;
import com.xbongbong.paas.pojo.dto.FormDataDeleteBatchDTO;
import com.xbongbong.paas.pojo.dto.FormDataUpdateDTO;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.service.dynamic.crm.strategy.AbstractDynamicStrategy;
import com.xbongbong.paas.service.dynamic.crm.strategy.DecisionTreeDynamicStrategy;
import com.xbongbong.parent.interfaces.DynamicStrategy;
import com.xbongbong.paas.service.dynamic.crm.strategy.MainBusinessDynamicStrategy;
import com.xbongbong.paas.service.dynamic.crm.strategy.PushNotifyDynamicStrategy;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.pro.businesstage.pojo.dto.StageJumpDealDTO;
import com.xbongbong.pro.customercommunicate.pojo.dto.DynamicDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicArchiveDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicCheckJoinTeamDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicDeleteDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicLabelDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicRefInfoDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicSaveDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicStageJumpDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicUpdateBatchDTO;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicUpdateDTO;
import com.xbongbong.pro.formdata.pojo.vo.BeforeUpdateVO;
import com.xbongbong.pro.formdata.pojo.vo.UpdateVO;
import com.xbongbong.pro.opportunity.pojo.JudgeStageChangedPojo;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.enums.ProjectLogEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.enums.dictionary.DictionaryEnum;
import com.xbongbong.saas.service.DictionaryService;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.UserEntity;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 *机会
 *
 *@author weijianxun
 */
@Service("opportunityDynamicStrategyImpl")
public class OpportunityDynamicStrategyImpl extends AbstractDynamicStrategy
        implements DynamicStrategy, PushNotifyDynamicStrategy, DecisionTreeDynamicStrategy, MainBusinessDynamicStrategy {

    private final Logger LOG = LoggerFactory.getLogger(OpportunityDynamicStrategyImpl.class);

    private static final Map<String, Integer> refTextToLogTypeMap = new HashMap<>();

    static {
        refTextToLogTypeMap.put(SalesOpportunityEnum.CUSTOMER_NAME.getAttr(), ProjectLogEnum.CUSTOMER_REF.getSubType());
        refTextToLogTypeMap.put(SalesOpportunityEnum.CONTACT_NAME.getAttr(), ProjectLogEnum.CONTACT_REF.getSubType());
    }

    @Resource
    private DictionaryService dictionaryService;

    public static Map<String, Integer> getRefTextToLogTypeMap(){
        return Collections.unmodifiableMap(refTextToLogTypeMap);
    }

    @Override
    public List<Integer> type() {
        return Arrays.asList(XbbRefTypeEnum.SALES_OPPORTUNITY.getCode());
    }

    @Override
    @Async("dynamicThreadPool")
    public void save(DynamicSaveDTO dynamicSaveDTO) {
        try {
            SaasFormSaveDTO saasFormSaveDTO = dynamicSaveDTO.getSaasFormSaveDTO();
            UserEntity creator = dynamicSaveDTO.getCreator();
            String creatorUserName = creator.getName();
            PaasFormDataEntity newPaasFormDataEntity = saasFormSaveDTO.getNewPaasFormDataEntity();
            Long oppId = newPaasFormDataEntity.getId();
            JudgeStageChangedPojo judgeStageChangedPojo = dynamicSaveDTO.getJudgeStageChangedPojo();
            JSONObject newData = newPaasFormDataEntity.getData();
            String salesStageCode = FastJsonHelper.getStringOrDefaultFromFormData(newData, SalesOpportunityEnum.SALE_STAGE.getAttr(), "");
            String corpid = newPaasFormDataEntity.getCorpid();
            Long formId = newPaasFormDataEntity.getFormId();
            String serialNo = newPaasFormDataEntity.getSerialNo();
            String memo;
            List<String> memoPlaceHolder;
            PaasFormEntity paasForm = getPaasForm(corpid, formId, saasFormSaveDTO.getBusinessType());
            if (Objects.equals(saasFormSaveDTO.getIsImport(), BasicConstant.ONE)) {
                if (StringUtil.isNotEmpty(salesStageCode) && Objects.nonNull(judgeStageChangedPojo)){
                    memo = CrmLogMemoConstant.DYNAMIC_USER_IMPORT_STAGE;
                    memoPlaceHolder = DynamicDTO.initMemoHolder(creatorUserName, paasForm.getName(), judgeStageChangedPojo.getTargetStageName());
                }else {
                    memo = CrmLogMemoConstant.DYNAMIC_USER_IMPORT;
                    memoPlaceHolder = DynamicDTO.initMemoHolder(creatorUserName, paasForm.getName(), serialNo);
                }
            } else {
                if (StringUtil.isNotEmpty(salesStageCode) && Objects.nonNull(judgeStageChangedPojo)) {
                    memo = CrmLogMemoConstant.DYNAMIC_USER_ADD_STAGE;
                    memoPlaceHolder = DynamicDTO.initMemoHolder(creatorUserName, paasForm.getName(), judgeStageChangedPojo.getTargetStageName());
                } else {
                    memo = CrmLogMemoConstant.DYNAMIC_USER_ADD;
                    memoPlaceHolder = DynamicDTO.initMemoHolder(creatorUserName, paasForm.getName(), serialNo);
                }
            }
            saveRefUpDynamic(dynamicSaveDTO, refTextToLogTypeMap, paasForm, DynamicRefInfoDTO.initDynamicRefInfoDTO(oppId, saasFormSaveDTO.getBusinessType(), serialNo), memo, memoPlaceHolder, ProjectLogEnum.OPPORTUNITY_CREATE.getSubType());
        } catch (Exception e) {
            LOG.error("com.xbongbong.paas.service.dynamic.crm.strategy.impl.OpportunityStrategyImpl.save", e);
        }
    }

    @Override
    @Async("dynamicThreadPool")
    public void update(DynamicUpdateDTO dynamicUpdateDTO) {
        try {
            FormDataUpdateDTO formDataUpdateDTO = dynamicUpdateDTO.getFormDataUpdateDTO();
            BeforeUpdateVO beforeUpdateVO = dynamicUpdateDTO.getBeforeUpdateVO();
            UpdateVO updateVO = dynamicUpdateDTO.getUpdateVO();
            PaasFormDataEntity paasFormDataEntity = beforeUpdateVO.getPaasFormDataEntity();
            PaasFormEntity paasForm = getPaasForm(formDataUpdateDTO.getCorpid(), paasFormDataEntity.getFormId(), formDataUpdateDTO.getBusinessType());
            DynamicDTO dynamicDTO = initDynamicDTO(updateVO.getUserVO().getUserId(), CrmLogMemoConstant.DYNAMIC_USER_UPDATE_BASE_INFO, ProjectLogEnum.OPPORTUNITY_UPDATE.getSubType(),
                    DynamicDTO.initMemoHolder(updateVO.getUserVO().getName(), paasForm.getName()), paasForm, formDataUpdateDTO.getSaasMark(), paasFormDataEntity.getId());
            insertDynamic(Collections.singletonList(dynamicDTO), formDataUpdateDTO.getCorpid());
        } catch (Exception e) {
            LOG.error("com.xbongbong.paas.service.dynamic.crm.strategy.impl.OpportunityStrategyImpl.update", e);
        }
    }

    @Override
    @Async("dynamicThreadPool")
    public void batchUpdate(DynamicUpdateBatchDTO dynamicUpdateBatchDTO) {
        try {
            super.batchUpdate(dynamicUpdateBatchDTO, ProjectLogEnum.OPPORTUNITY_UPDATE.getSubType());
        } catch (Exception e) {
            LOG.error("com.xbongbong.paas.service.dynamic.crm.strategy.impl.OpportunityDynamicStrategyImpl.batchUpdate", e);
        }
    }

    @Override
    @Async("dynamicThreadPool")
    public void batchDelete(DynamicDeleteDTO dynamicDeleteDTO) {
        try {
            FormDataDeleteBatchDTO formDataDeleteBatchDTO = dynamicDeleteDTO.getFormDataDeleteBatchDTO();
            List<PaasFormDataEntityExt> allowDeletePaasFormDatas = dynamicDeleteDTO.getAllowDeletePaasFormDatas();
            String corpid = formDataDeleteBatchDTO.getCorpid();

            if (CollectionUtils.isNotEmpty(allowDeletePaasFormDatas)) {
                PaasFormEntity paasForm = getPaasForm(corpid, formDataDeleteBatchDTO.getFormId(), formDataDeleteBatchDTO.getBusinessType());
                batchRefSaveUpDynamicByDeleteBatch(dynamicDeleteDTO, refTextToLogTypeMap, paasForm, SalesOpportunityEnum.SERIAL_NO.getAttr(), ProjectLogEnum.OPPORTUNITY_DELETE.getSubType());
            }
        } catch (Exception e) {
            LOG.error("com.xbongbong.paas.service.dynamic.crm.strategy.impl.OpportunityStrategyImpl.batchDelete", e);
        }
    }

//    @Override
//    @Async("dynamicThreadPool")
//    public void throughDelete(DynamicThroughDeleteDTO dynamicThroughDeleteDTO) {
//
//    }

    @Override
    @Async("dynamicThreadPool")
    public void checkJoinTeam(DynamicCheckJoinTeamDTO dynamicCheckJoinTeamDTO) {
        try {
            super.checkJoinTeam(dynamicCheckJoinTeamDTO, ProjectLogEnum.OPPORTUNITY_TEAM_ADD.getSubType());
        } catch (Exception e) {
            LOG.error("com.xbongbong.paas.service.dynamic.crm.strategy.impl.OpportunityDynamicStrategyImpl.checkJoinTeam", e);
        }
    }

    @Override
    @Async("dynamicThreadPool")
    public void archive(DynamicArchiveDTO dynamicArchiveDTO) {
        try {
            super.archive(dynamicArchiveDTO, ProjectLogEnum.OPPORTUNITY_ARCHIVE.getSubType());
        } catch (Exception e) {
            LOG.error("com.xbongbong.paas.service.dynamic.crm.strategy.impl.OpportunityDynamicStrategyImpl.archive", e);
        }
    }

    @Override
    @Async("dynamicThreadPool")
    public void stageJump(DynamicStageJumpDTO dynamicStageJumpDTO) {
        try {
            StageJumpDealDTO stageJumpDealDTO = dynamicStageJumpDTO.getStageJumpDealDTO();
            String corpid = stageJumpDealDTO.getCorpid();
            String memo = dynamicStageJumpDTO.getMemo();
            PaasFormDataEntityExt paasFormDataEntityExt = dynamicStageJumpDTO.getPaasFormDataEntityExt();
            Long opportunityId = paasFormDataEntityExt.getDataId();
            Long formId = stageJumpDealDTO.getFormId();

            PaasStageEntity toStageEntity = stageJumpDealDTO.getToStageEntity();
            Integer stageType = toStageEntity.getType();
            PaasStageEntity fromStageEntity = stageJumpDealDTO.getFromStageEntity();
            String nowStageName = fromStageEntity == null ? "开始阶段" : fromStageEntity.getName();
            // String preStageMemo = StringUtil.isEmpty(nowStageName) ? "" : I18nMessageUtil.getMessage(CommonConstant.BY) + "“" + nowStageName + "”";
            String stageName = toStageEntity.getName();
            PaasFormEntity paasForm = getPaasForm(corpid, stageJumpDealDTO.getFormId(), stageJumpDealDTO.getBusinessType());
            if(StringUtil.isEmpty(memo)) {
                if (Objects.equals(stageType, StageTypeEnum.FAIL_STAGE.getType())) {
                    //流失
                    Map<String, String> wastageReasonMap = dictionaryService.getDictionaryMap(DictionaryEnum.SALE_STAGE_WASTAGE, corpid, formId);
                    memo = String.format(I18nMessageUtil.getMessage(CrmLogMemoConstant.DYNAMIC_USER_SALES_STAGE_CHANGES_LOSE_REASON), stageJumpDealDTO.getLoginUserName(),
                            paasForm.getName(), nowStageName, stageName, wastageReasonMap.get(stageJumpDealDTO.getReasonId().toString()), stageJumpDealDTO.getMemo());

                } else {
                    memo = String.format(I18nMessageUtil.getMessage(CrmLogMemoConstant.DYNAMIC_USER_STAGE), stageJumpDealDTO.getLoginUserName(), paasForm.getName(), nowStageName, stageName);
                }
            }

            DynamicDTO dynamicDTO = initDynamicDTO(stageJumpDealDTO.getUserId(), memo, ProjectLogEnum.OPPORTUNITY_STAGE.getSubType(), null, paasForm, stageJumpDealDTO.getSaasMark(), opportunityId);
            dynamicDTO.setRefId(paasFormDataEntityExt.getId());
            dynamicDTO.setRefBusinessType(stageJumpDealDTO.getBusinessType());
            dynamicDTO.setRefName(paasFormDataEntityExt.getSerialNo());
            JSONObject data = paasFormDataEntityExt.getData();
            refTextToLogTypeMap.forEach((refText,logType)->{
                Long dataId = data.getLong(refText);
                if (Objects.nonNull(dataId)) {
                    initMainBusinessIdOrRefIdByLogType(logType, dynamicDTO, dataId);
                }
            });

            insertDynamic(Collections.singletonList(dynamicDTO), corpid);
        } catch (Exception e) {
            LOG.error("com.xbongbong.paas.service.dynamic.crm.strategy.impl.OpportunityStrategyImpl.stageJump", e);
        }
    }

    @Override
    @Async("dynamicThreadPool")
    public void label(DynamicLabelDTO dynamicLabelDTO) {
        try {
            super.label(dynamicLabelDTO, ProjectLogEnum.OPPORTUNITY_UPDATE.getSubType());
        } catch (Exception e) {
            LOG.error("com.xbongbong.paas.service.dynamic.crm.strategy.impl.OpportunityDynamicStrategyImpl.label", e);
        }
    }
}
